﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Operators;
using Satates;
using Arbore;
using Common;

namespace Algorithms.WidthSearch
{
    public class WidthSearchAlgo : Algorithm
    {
        private int expandCounter;
        private bool result = false;
        Arbore.Arbore ab;
        Arbore.Nod nodCurent;
        public WidthSearchAlgo(State iState, List<State> fStates, List<iOperator> opr, List<string> log, ref Arbore.Arbore Ab) : base(iState, fStates, opr, log) {
            ab = Ab;
        }

        private bool solve(int initialValue, int finalValue)
        {
            expandCounter = 0;
            for (int i = initialValue; i <= finalValue; i++)
            {
                if (expand(btStack.ElementAt(i))) { result = true; return true; }
            }
            if (initialValue > finalValue)
            {
                return false;
            }
            return solve(initialValue , btStack.Count()-1);
            
        }

        private bool expand(State thisState)
        {
            Nod nd = ab.CurrentNod;
            for (int i = 0; i <= operatorNumber; i++)
            {

                if (operators.ElementAt(i).available(thisState.CurrentState))
                {
                    var m = (Template)thisState.CurrentState.Clone();
                    State auxiliary = new State(operators.ElementAt(i).execute(m), operators.ElementAt(i));
                    
                    if (!found(auxiliary)) { 
                        expandCounter++; 
                        btStack.Push(auxiliary);
                        ab.CurrentNod = nd;
                        ab.AddS(new Nod(operators.ElementAt(i).ToString() + Environment.NewLine + auxiliary.ToString()));
                        if (solutionFound(auxiliary)) return true; 
                    }
                }
            }

            return false;
        }


        public override bool solveProblem()
        {
            ab.AddS(new Nod(initialState.ToString()));
            result = false;
            solve(0, 0);
            if (result) return true;
            return false;

        }

        public override void init()
        {
            expandCounter = 0;
        }


    }
}
